import React, { Fragment, useEffect, useCallback, useState, useRef } from 'react'
import { CSSTransition } from 'react-transition-group'
import { useHistory } from 'react-router-dom'
import { ToastNotification } from '@/components/Toast'
import { DEVLAKE_ENDPOINT } from '@/utils/config'
import request from '@/utils/request'
import {
  H2, Button, Icon, Intent,
  Card, Elevation, Tag,
  Tooltip,
  Position,
  Spinner,
  Colors
} from '@blueprintjs/core'
import '@/styles/offline.scss'

const Offline = (props) => {
  const {
    pollTimer = 7000,
    retryLimit = 100,
    endpointUrl = null
  } = props
  const history = useHistory()
  const testInterval = useRef()
  const retryCount = useRef()

  const [apiEndpointUrl, setApiEndpointUrl] = useState(`${DEVLAKE_ENDPOINT}/env`)
  const [isOffline, setIsOffline] = useState(true)
  const [testResponse, setTestResponse] = useState({})
  const [testStatus, setTestStatus] = useState(504)
  const [cardReady, setCardReady] = useState(false)
  const [aborted, setAborted] = useState(false)

  const testEndpoint = useCallback(async () => {
    console.log('>> OFFLINE MODE -  TESTING ENDPOINT!', apiEndpointUrl)
    retryCount.current++
    try {
      setCardReady(false)
      const t = await request.get(apiEndpointUrl)
      setTestResponse(t.data)
      setTestStatus(() => t.status ?? 504)
    } catch (e) {
      setTestResponse(tR => { return { ...tR, data: [], error: e.response.data, statusCode: e.response.status } })
      setTestStatus(504)
    }
  }, [apiEndpointUrl])

  useEffect(() => {
    console.log('>> OFFLINE MODE -  ENDPOINT TEST RESPONSE = ', testResponse)
    if (testResponse?.error) {
      ToastNotification.clear()
      ToastNotification.show({ message: testResponse.error ?? 'Network Error 504 (Gateway Timeout)', intent: 'danger', icon: 'error' })
    }
    setTimeout(() => {
      setCardReady(true)
    }, 0)
  }, [testResponse])

  useEffect(() => {
    console.log('>> OFFLINE MODE - CURRENT API HTTP/STATUS: ', testStatus)
    setIsOffline(testStatus !== 200)
    if (testStatus === 200) {
      clearInterval(testInterval.current)
      ToastNotification.clear()
      ToastNotification.show({ message: 'DevLake API Online', intent: 'danger', icon: 'tick-circle' })
      console.log('>> OFFLINE MODE - API RESTORED, TERMINATING POLLING!!!')
    }
  }, [testStatus])

  useEffect(() => {
    console.log('>> OFFLINE MODE -  OFFLINE CHECK?', isOffline)
  }, [isOffline])

  useEffect(() => {
    testEndpoint()
  }, [testEndpoint])

  useEffect(() => {
    testInterval.current = setInterval(() => {
      setTestStatus(504)
      testEndpoint()
      // retryCount.current++
    }, pollTimer)

    return () => {
      clearInterval(testInterval.current)
      setCardReady(false)
      setAborted(false)
    }
  }, [pollTimer, testEndpoint])

  useEffect(() => {
    console.log('>> OFFLINE MODE (MOUNTED) - ENDPOINT URL ...', endpointUrl)
    retryCount.current = 1
    setAborted(false)
    setApiEndpointUrl((url) => endpointUrl !== null && endpointUrl !== url ? endpointUrl : `${DEVLAKE_ENDPOINT}/env`)
  }, [endpointUrl])

  useEffect(() => {
    if (retryCount.current >= retryLimit) {
      console.log('>> OFFLINE MODE - RETRY LIMIT EXCEEDED, TERMINATING POLLING!!!')
      clearInterval(testInterval.current)
      setAborted(true)
      ToastNotification.clear()
      ToastNotification.show({ message: 'Retry Limit Exceeded, please refresh your browser.', intent: 'danger', icon: 'error' })
    }
  }, [retryCount.current, retryLimit])

  return (
    <>
      {(
        <div
          className={`offline-wrapper ${isOffline ? 'is-offline' : 'is-online'}`}
        >
          <div
            style={{ maxWidth: '500px', margin: '0 auto', display: 'flex', height: '100%', flexDirection: 'column' }}
          >
            <div style={{ margin: 'auto auto', padding: '16px' }}>
              <CSSTransition in={cardReady} timeout={900} classNames='offline-card'>
                <Card
                  elevation={Elevation.THREE}
                >
                  <span style={{ display: 'block', position: 'absolute', right: 0, top: 0, margin: '10px' }}>
                    {isOffline ? <Spinner size={16} /> : <Icon icon='tick-circle' size={16} color={Colors.GRAY4} />}
                  </span>
                  <div style={{ textAlign: 'center' }}>
                    {isOffline
                      ? (
                        <img
                          style={{ margin: '0px auto 10px auto', width: '54px', height: '54px', maxWidth: '5 4px' }}
                          width={54}
                          height={54}
                          // eslint-disable-next-line max-len
                          src=''
                        />
                        )
                      : (
                        <img
                          style={{ margin: '0px auto 10px auto', width: '64px', height: '64px', maxWidth: '64px' }}
                          width={64}
                          height={64}
                        // eslint-disable-next-line max-len
                          src=''
                        />
                        )}
                  </div>
                  <H2 style={{ fontFamily: '"Montserrat", sans-serif' }}>DevLake API&nbsp;
                    <CSSTransition in={cardReady} timeout={300} classNames='offline-card-os'>
                      {isOffline
                        ? (
                          <strong style={{
                            padding: '0 3px',
                            fontWeight: '900',
                            backgroundColor: 'rgba(220,50,50,0.2)',
                            color: 'rgb(212, 69, 36)'
                          }}
                          >
                            Offline
                          </strong>
                          )
                        : (
                          <strong style={{
                            padding: '0 3px',
                            fontWeight: '900',
                            backgroundColor: 'rgba(50,221,80,0.2)',
                            color: 'rgb(36, 212, 72)'
                          }}
                          >
                            Online
                          </strong>

                          )}
                    </CSSTransition>
                  </H2>
                  <Tag><code>DEVLAKE_ENDPOINT: {DEVLAKE_ENDPOINT}</code></Tag>
                  {isOffline
                    ? (
                      <>
                        <p style={{ fontSize: '16px', fontFamily: '"JetBrains Mono", monospace', color: '#222222' }}>
                          Please wait for the&nbsp;
                          <strong>Lake API</strong> to start before accessing the <strong>Configuration Interface</strong>.
                        </p>
                        <Tooltip
                          intent={Intent.PRIMARY}
                          className='offline-continue-tooltip'
                          targetClassName='offline-continue-tooltip-target'
                          content={(<><Icon size={14} icon='warning-sign' /> Proceed with caution.</>)}
                          position={Position.RIGHT}
                          style={{ cursor: 'pointer' }}
                        >
                          <Button
                            intent={Intent.DANGER} icon='warning-sign'
                            style={{ fontWeight: 700 }}
                            onClick={() => history.replace('/')}
                            large
                          >Continue
                          </Button>
                        </Tooltip>
                        <Button
                          icon='refresh' text='Refresh'
                          minimal
                          style={{ marginLeft: '5px' }}
                          disabled={!cardReady}
                          onClick={() => testEndpoint()}
                          large
                        />
                      </>
                      )
                    : (
                      <>
                        <p style={{ fontSize: '16px', fontFamily: '"JetBrains Mono", monospace', color: '#222222' }}>
                          Connectivity to the Lake API service was successful (PORT <strong>{testResponse.PORT}</strong>).
                        </p>
                        <Button
                          icon='cog' intent={Intent.PRIMARY}
                          onClick={() => history.replace('/')}
                          large
                        >
                          Open Dashboard
                        </Button>
                        <a
                          href='https://github.com/merico-dev/lake/blob/main/README.md'
                          target='_blank'
                          rel='noreferrer'
                          style={{ marginLeft: '5px' }} className='bp3-button bp3-large bp3-minimal'
                        >
                          <Icon icon='help' size={16} style={{ marginRight: '5px' }} />
                          Read Documentation
                        </a>
                      </>
                      )}
                </Card>
              </CSSTransition>
              <div style={{ margin: '10px 5px 10px 5px', display: 'flex', justifyContnt: 'flex-start' }}>
                <img src='/logo.svg' width={20} style={{ width: '20px', marginTop: '3px', marginRight: '5px', alignSelf: 'flex-start' }} />
                <div style={{ color: 'rgba(33, 33, 33, 0.6)' }}>
                  {isOffline
                    ? (
                      <>
                        <strong style={{ fontFamily: 'Montserrat', fontWeight: 900, letterSpacing: '2px' }}>
                          OFFLINE &middot;&nbsp;
                        </strong>
                        <a
                          href='https://github.com/merico-dev/lake/blob/main/README.md'
                          target='_blank'
                          rel='noreferrer'
                          style={{ fontWeight: 400, letterSpacing: 0 }}
                        >
                          Documentation on <span style={{ fontWeight: 800 }}>GitHub</span>
                        </a>
                        <br /> Please verify network connectivity if the problem persists.<br />
                        <strong style={{ fontWeight: 600, letterSpacing: '0px' }}>
                          {retryCount.current} failed attempt(s).
                        </strong>
                      </>
                      )
                    : (
                      <>
                        <strong style={{ fontFamily: 'Montserrat', fontWeight: 900, letterSpacing: '2px' }}>
                          ONLINE &middot;&nbsp;
                        </strong>
                        <a
                          href='/integrations'
                          style={{ color: 'rgba(50,50,50,0.6)', textDecoration: 'underline', fontWeight: 400, letterSpacing: 0 }}
                        >
                          Proceed with <span style={{ fontWeight: 800 }}>Data Integrations</span>
                        </a>
                        <br /> Lake API connection restored.
                      </>
                      )}

                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </>
  )
}

export default Offline
